package com.code.translate.plugins;

import com.code.translate.enums.Constants;
import com.code.translate.function.DocumentTranslatePlugin;
import com.code.translate.utils.HttpUtils;
import com.code.translate.utils.JsonpathUtils;
import com.code.translate.utils.StringUtils;
import org.springframework.http.HttpMethod;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ggh
 * @date 2022/10/16
 * <p>
 * 讯飞听见翻译
 */
public class IFlyRecTranslatePlugin extends DocumentTranslatePlugin {
    private final static String indexUrl = "https://fanyi.iflyrec.com/";
    private final static String translateUrl = "https://fanyi.iflyrec.com/TranslationService/v1/textTranslation?t=%s";

    private final static String UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36";
    private final static String ContentType = "application/json";
    private final static Integer signleTranslateTextLen = 2000;

    private static IFlyRecTranslatePlugin singleton = new IFlyRecTranslatePlugin();

    private IFlyRecTranslatePlugin() {
    }

    public static IFlyRecTranslatePlugin getSingleton() {
        return singleton;
    }

    // todo 暂未实现
    @Override
    protected Map<String, Object> prepareDocuemnt() throws Exception {
        return null;
    }

    @Override
    public String doTranslateDocumentByStream(InputStream inputStream, Map<String, Object> params) throws Exception {
        return super.doTranslateDocumentByStream(inputStream, params);
    }

    @Override
    protected Map<String, Object> prepare() throws IOException {
        return null;
    }

    @Override
    protected String doTranslate(String text, Map<String, Object> params) throws Exception {
        String response;
        Map<String, String> headers = new HashMap<>(3);
        headers.put("User-Agent", UserAgent);
        headers.put("Referer", indexUrl);
        headers.put("Content-Type", ContentType);

        String currentTranslateUrl = String.format(translateUrl, System.currentTimeMillis());
        if (text.length() > signleTranslateTextLen) {
            List<String> singleTextList = StringUtils.splitString(text, signleTranslateTextLen, Constants.SEGEMENT);

            Map<String, Object> requestParams = structCommonParams();

            StringBuffer buffer = new StringBuffer();
            for (String singleText : singleTextList) {
                loadTextParams(requestParams, singleText);

                response = HttpUtils.req(currentTranslateUrl, HttpMethod.POST, headers, requestParams);

                if (response != null && response.contains("code\":\"000000")) {
                    buffer.append(JsonpathUtils.read(response, "$.biz[*].translateResult") + "\n");
                }
            }
            return buffer.toString();
        } else {
            Map<String, Object> requestParams = structParams(text);

            response = HttpUtils.req(currentTranslateUrl, HttpMethod.POST, headers, requestParams);

            if (response != null && response.contains("code\":\"000000")) {
                return JsonpathUtils.read(response, "$.biz[*].translateResult");
            }
            return null;
        }
    }

    private static Map<String, Object> structParams(String text) throws Exception {
        Map<String, Object> params = structCommonParams();
        return loadTextParams(params, text);
    }

    private static Map<String, Object> structCommonParams() {
        Map<String, Object> params = new HashMap<>(3);
        params.put("from", "2");
        params.put("to", "1");

        return params;
    }

    private static Map<String, Object> loadTextParams(Map<String, Object> params, String text) throws Exception {
        String[] lines = text.split("\n");

        List<ContentData> contentDataList = new ArrayList<>(lines.length);
        for (String line : lines) {
            if (!"".equals(line.trim())) {
                contentDataList.add(new ContentData(0, line));
            }
        }

        params.put("contents", contentDataList);

        return params;
    }


    static class ContentData {
        private Integer frontBlankLine = 0;
        private String text;

        public ContentData(Integer frontBlankLine, String text) {
            this.frontBlankLine = frontBlankLine;
            this.text = text;
        }

        public Integer getFrontBlankLine() {
            return frontBlankLine;
        }

        public String getText() {
            return text;
        }
    }
}
